package com.gmrz.webauthn.db.dao;

import com.gmrz.uaf.db.DAOException;
import com.gmrz.util.db.DBUtil;
import com.gmrz.webauthn.protocol.v1.processor.WebAuthnErrorCode;
import com.gmrz.webauthn.protocol.v1.schema.WebAuthnPolicy;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class BaseWebAuthnPolicyDAO extends Dialect implements WebAuthnPolicyDAO {
    private static final Logger LOG = LogManager.getLogger(BaseWebAuthnPolicyDAO.class);

    public static final String _SQL_SELECT_ALL = "select pl_id,policy_name,auth_type,trans_type,tenant_id,createts from t_policy where auth_type >29 ";//30-40为fido2

    private Connection conn_;

    @AssistedInject
    public BaseWebAuthnPolicyDAO(@Assisted Connection conn_) {
        this.conn_ = conn_;
    }


    private WebAuthnPolicy readResultSet(ResultSet rs) throws DAOException {
        WebAuthnPolicy webAuthnPolicy = new WebAuthnPolicy();
        try {
            int offset = 1;
            webAuthnPolicy.setWpId(rs.getString(offset++));
            webAuthnPolicy.setPolicyName(rs.getString(offset++));
            webAuthnPolicy.setAuthType(rs.getString(offset++));
            webAuthnPolicy.setTransType(rs.getString(offset++));
            webAuthnPolicy.setTenantId(rs.getString(offset++));
            webAuthnPolicy.setCreatets(rs.getTimestamp(offset));

            return webAuthnPolicy;

        } catch (SQLException sqle) {
            LOG.error("Failed to read the Tenant Config Data", sqle);
            throw new DAOException(WebAuthnErrorCode.ERROR_DATABASE_READ_ERROR, sqle);
        }
    }


    @Override
    public List<WebAuthnPolicy> find(WebAuthnPolicy webAuthnPolicy) throws DAOException {
        StringBuilder sql = new StringBuilder(_SQL_SELECT_ALL);
        PreparedStatement s = null;
        ResultSet rs = null;
        List<WebAuthnPolicy> result = new ArrayList<WebAuthnPolicy>();


        try {

            List<Object> paras = null;
            if (webAuthnPolicy != null) {

                paras = new ArrayList<Object>();

                if (StringUtils.isNotBlank(webAuthnPolicy.getWpId())) {
                    sql.append(" and pl_id = ?");
                    paras.add(webAuthnPolicy.getWpId());
                }

                if (StringUtils.isNotBlank(webAuthnPolicy.getPolicyName())) {
                    sql.append(" and policy_cname = ?");
                    paras.add(webAuthnPolicy.getPolicyName());
                }

                if (StringUtils.isNotBlank(webAuthnPolicy.getAuthType())) {
                    sql.append(" and auth_type = ?");
                    paras.add(webAuthnPolicy.getAuthType());
                }

                if (StringUtils.isNotBlank(webAuthnPolicy.getTransType())) {
                    sql.append(" and trans_type = ?");
                    paras.add(webAuthnPolicy.getTransType());
                }

                if (StringUtils.isNotBlank(webAuthnPolicy.getTenantId())) {
                    sql.append(" and tenant_id = ?");
                    paras.add(webAuthnPolicy.getTenantId());
                }
            }

            s = this.conn_.prepareStatement(sql.toString());

            if (paras != null && !paras.isEmpty()) {
                fillStatement(s, paras);
            }

            rs = s.executeQuery();

            while (rs.next()) {
                result.add(readResultSet(rs));
            }
        } catch (SQLException sqle) {
            LOG.error("The following SQL statement failed to execute:\n {}", sql);
            throw new DAOException(WebAuthnErrorCode.ERROR_DATABASE_READ_ERROR, sqle);
        } finally {
            DBUtil.close(rs);
            DBUtil.close(s);
        }

        return result;
    }
}
